;; Mode: LISP; Syntax: Common-lisp; Package: aklemme
;; Names: Ardell Klemme, Bruce Ho, Jimmy Cumming         Date: 11/05/12
;; Course: ICS 313   Assignment: 6
;; File: actions.lisp

; AK: displays current location and information about location, paths available
;     and objects in current location
(defun look ()
  (append (describe-location *location* *nodes*)
          (describe-paths *location* *edges*)
          (describe-objects *location* *objects* *object-locations*)))
         
; AK: walks in given direction, if it is a valid direction, else give error msg.
; AK: this now handles the command when no arguments are given
(defun walk (&optional (direction "nowhere"))
  (cond ((equal direction "nowhere")
         `(you must specify which direction to go.))
   (t
    (labels ((correct-way (edge)
             (eq (cadr edge) direction)))
    (let ((next (find-if #'correct-way (cdr (assoc *location* *edges*)))))
      (if next
          (progn (setf *location* (car next))
                 (look))
          '(you cannot go that way.)))))))

; AK: picks up an object if it exists in current location, puts onto body
;     (inventory).
; AK: This now handles the command without arguments
(defun pickup (&optional (object "nothing"))
  (cond ((equal object "nothing")
         `(you must specify something to pickup.))
        ((member object
                 (objects-at *location* *objects* *object-locations*))
         (push (list object 'body) *object-locations*)
          `(you are now carrying the ,object))
        (t '(you cannot get that.))))

; AK: lists all objects in inventory
(defun inventory ()
  (cons 'items- (objects-at 'body *objects* *object-locations*)))

; AK: checks inventory for a specific object, returns t/nil
(defun have (object)
    (member object (cdr (inventory))))
    
;;;======================Macro-actions===========================;;;

; AK: Set starting state for game conditions to nil.
(defparameter *warpcore-fixed* nil)
; (defparameter *drunk* nil) ;AK: adds to fail state (try to repair while drunk?)
(defparameter *metaphasic-transinducer-array-built* nil)
(defparameter *good-power-supply-chosen* nil)
(defparameter *bad-power-supply-chosen* nil)
(defparameter *power-supply-incorporated* nil)
; (defparameter *plasma-rifle-shot* nil)

; AK: In order to fix the warp-core, we must first build the piece we need.
;     here we build the metaphasic-transinducer-array
(game-action integrate positronic-relay inverter-casing main-engineering
             (cond ((not (have 'inverter-casing))
                    '(you're missing the inverter-casing.))
                   ((not (have 'plasma-conduit))
                    '(you're missing the plasma-conduit.))
                   ((not (have 'positronic-relay))
                    '(you're missing the positronic-relay.))                  
                   ((equal *metaphasic-transinducer-array-built* t)
                    '(the metaphasic-transinducer-array is already built.))
                   (t (progn
                         (setf *metaphasic-transinducer-array-built* 't)
                         (new-object metaphasic-transinducer-array main-engineering)
                         (setf *objects*
                               (remove 'inverter-casing *objects*))
                         (setf *objects*
                               (remove 'plasma-conduit *objects*))
                         (setf *objects*
                               (remove 'positronic-relay *objects*))
                         (pickup 'metaphasic-transinducer-array)
                         '(you have successfully built the metaphasic-transinducer-array.
                           now you must choose the right power-supply.
                           then you just need to incorporate the appropriate power-supply
                           into the metaphasic-transinducer-array.)))))

; AK: The user needs to choose a power supply.
(defun choose (&optional (power "none"))
  (cond
      ((or 
          (equal *good-power-supply-chosen* t)
          (equal *bad-power-supply-chosen* t))
          `(you have already chosen your power supply.))
      ((equal power "none")
        `(you must specify which power supply you choose.))
      ((equal power 'anti-matter-warhead)
        (progn 
          (setf *good-power-supply-chosen* 't)
          `(you have chosen the anti-matter-warhead as your power-supply.)))
      ((equal power 'stable-powercell)
        (progn 
          (setf *bad-power-supply-chosen* 't)
          `(you have chosen the stable-powercell as your power-supply.)))
      (t `(that is not a suitable power-supply.))))

; AK: In order to fix the warp-core, we must first build the piece we need.
;     here we incorporate the power-supply (and introduce a fail-scenario/choice)
(game-action incorporate metaphasic-transinducer-array power-supply main-engineering
             (cond
               ; AK: CASE 0: already incorporated.
               ((equal *power-supply-incorporated* t)
                '(you have already incorporated the power-supply.
                  now you just need to fix the warp-core.))
               ; AK: CASE 1:no power-supply chosen
               ((and 
                 (not (equal *good-power-supply-chosen* t))
                 (not (equal *bad-power-supply-chosen* t)))
                '(you must first choose which power-supply to use.)
               )
               ; AK: CASE 2:bad power chosen
               ((equal *bad-power-supply-chosen* t)
                (progn
                  (setf *power-supply-incorporated* 't)
                  (setf *objects*
                       (remove 'stable-powercell *objects*))
                  '(you have successfully incorporated the stable-powercell into
                    the metaphasic-transinducer-array. now you can attach the 
                    metaphasic-transinducer-array to the warp-core to repair it.)))
               ; AK: CASE 3:good power chosen
               (t (progn
                    (setf *power-supply-incorporated* 't)
                    (setf *objects*
                         (remove 'anti-matter-warhead *objects*))
                    '(you have successfully incorporated the anti-matter-warhead into
                      the metaphasic-transinducer-array. now you can attach the 
                      metaphasic-transinducer-array to the warp-core to repair it.)))))

; AK: This is the final action of repairing the warp-core reactor.
;     The game will either win or lose here.  (in addition to any
;     other possible lose scenarios)
(game-action attach metaphasic-transinducer-array warp-core main-engineering
          (cond
            ; AK: CASE 0: you've already to fix the warp-core
            ((equal *warpcore-fixed* t)
             '(you have already fixed the warp-core.
               you do not need to fix it again.
               you may now relax in the ship lounge.))
            ; AK: CASE 1: you're not ready to fix the core
            ((not (equal *power-supply-incorporated* t))
             '(you must first incorporate a power supply into a
               metaphasic-transinducer-array.))
            ; AK: CASE 2: you win!
            ((equal *good-power-supply-chosen* t)
              (progn 
                (setf *warpcore-fixed* 't)
                '(you attach the metaphasic-transinducer-array.
                    after a few seconds you see that the power levels
                    of the containment field begin to stabilize rapidly.
                    you have used the correct power source. 
                    the warp-core is repaired! - you win! the end.)))
            ; AK: CASE 3: you lose!
            (t '(you attach the metaphasic-transinducer-array.
               after a few seconds you see that the power levels
               of the containment field begin to fluctuate rapidly.
               you should have used the unstable power source. 
               it is too late to respond as the core ignites and 
               inverts the laws of physics through the inverter 
               tearing the very fabric of space-time to shreds.
               the entire universe explodes! - you lose! the end.))))